package com.yzy.util;

import com.yzy.pojo.JwtUser;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 杨志远
 * @implNote token创建、检查和校验方法
 * @date 2024/12/17 11:24
 */
@Slf4j
public class TokenUtil {
    /**
     * 盐值
     */
    private static final String SALT_KEY = "links";
    /**
     * token有效期
     */
    private static final long TOKEN_VALIDITY = 86400000;
    /**
     * base64秘钥
     */
    private final static String SECRET_KEY = Base64.getEncoder().encodeToString(SALT_KEY.getBytes(StandardCharsets.UTF_8));

    /**
     * token创建
     *
     * @param userId
     * @param clientId
     * @param role
     * @return
     */
    public static String createToken(String userId, String clientId, String role) {
        // 设置token过期时间
        long expireTime = System.currentTimeMillis() + TOKEN_VALIDITY;
        // 进行时间的类型的转化
        Date dateTime = new Date(expireTime);
        // 创建一个负载的claim对象
        Map<String, Object> claims = new HashMap<String, Object>(100);
        claims.put("userId", userId);
        claims.put("role", role);
        // 设置token权限
        String authorities = Base64.getEncoder().encodeToString(role.getBytes(StandardCharsets.UTF_8));
        return Jwts.builder()
                .setClaims(claims)
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                // 设置签收对象（客户端）
                .setAudience(clientId)
                .setIssuer("")
                .setIssuedAt(new Date())
                .setSubject(String.valueOf(userId))
                .setExpiration(dateTime)
                .compact();
    }

    public static JwtUser checkToken(String authToken) {
        if (validateToken(authToken)) {
            // 对token中的信息进行仔解析获取claims对象
            Claims claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(authToken).getBody();
            String userId = (String) claims.get("userId");
            String role = (String) claims.get("role");
            return new JwtUser().setUserId(userId).setRole(role).setValid(true);
        }
        log.error("token失效");
        return new JwtUser().setValid(false);
    }

    /**
     * 校验token是否有效
     *
     * @param authToken
     * @return
     */
    private static boolean validateToken(String authToken) {
        try {
            // 第一步就是解析，第二部就是验证秘钥，第三步就是验证签名，这三部是最常用的方式
            Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(authToken);
            return true;
        } catch (Exception e) {
            log.error("无效的token：" + authToken);
        }
        return false;
    }
}